package org.zjx.listener;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 事件管理器类，用于注册、排序、触发事件监听器，支持全局和线程局部监听器，并可异步触发事件。
 */
public class EventManager {

    // 全局监听器：所有线程共享的监听器
    private final Map<String, List<EventListenerWithPriority>> globalListeners = new HashMap<>();
    // 线程局部监听器：每个线程有独立的监听器
    private final ThreadLocal<Map<String, List<EventListenerWithPriority>>> threadLocalListeners = ThreadLocal.withInitial(HashMap::new);

    // 异步事件线程池
    private final ExecutorService executorService;

    /**
     * 构造函数，初始化事件管理器并创建指定大小的线程池
     *
     * @param threadPoolSize 线程池的大小，用于异步事件处理
     */
    public EventManager(int threadPoolSize) {
        executorService = Executors.newFixedThreadPool(threadPoolSize);
    }

    /**
     * 添加事件监听器
     *
     * @param event 事件名称
     * @param listener 事件监听器对象
     * @param priority 监听器的优先级，优先级高的先执行
     * @param isAsync 监听器是否异步执行
     * @param isGlobal 是否是全局监听器，如果为 true 则为全局监听器
     */
    public synchronized void addListener(String event, EventListener listener, int priority, boolean isAsync, boolean isGlobal) {
        EventListenerWithPriority listenerWithPriority = new EventListenerWithPriority(listener, isAsync, priority);

        if (isGlobal) {
            // 添加全局监听器
            globalListeners.computeIfAbsent(event, k -> new CopyOnWriteArrayList<>()).add(listenerWithPriority);
        } else {
            // 添加线程局部监听器
            threadLocalListeners.get().computeIfAbsent(event, k -> new CopyOnWriteArrayList<>()).add(listenerWithPriority);
        }

        // 按照优先级排序
        sortListeners(event, isAsync, isGlobal);
    }

    /**
     * 发布事件（同步方式）
     *
     * @param event 事件名称
     */
    public void triggerEvent(String event) {
        // 触发全局监听器
        triggerListeners(globalListeners.get(event), false);

        // 触发线程局部监听器
        triggerListeners(threadLocalListeners.get().get(event), false);
    }

    /**
     * 发布事件（异步方式）
     *
     * @param event 事件名称
     */
    public void triggerAsyncEvent(String event) {
        // 异步触发全局监听器
        triggerListeners(globalListeners.get(event), true);

        // 异步触发线程局部监听器
        triggerListeners(threadLocalListeners.get().get(event), true);
    }

    /**
     * 触发监听器，根据是否异步来执行监听器的方法
     *
     * @param listeners 事件监听器列表
     * @param isAsync 是否异步触发事件
     */
    private synchronized void triggerListeners(List<EventListenerWithPriority> listeners, boolean isAsync) {
        if (listeners != null) {
            for (EventListenerWithPriority listenerWithPriority : listeners) {
                boolean listenerAsync = listenerWithPriority.isAsync();  // 获取监听器的 isAsync 状态
                if (listenerAsync || isAsync) {
                    // 异步事件处理
                    executorService.submit(() -> listenerWithPriority.getListener().onEvent("Async event triggered"));
                } else {
                    // 同步事件处理
                    listenerWithPriority.getListener().onEvent("Event triggered");
                }
            }
        }
    }

    /**
     * 按照优先级对事件监听器进行排序
     *
     * @param event 事件名称
     * @param isAsync 是否异步触发
     * @param isGlobal 是否全局监听器
     */
    private void sortListeners(String event, boolean isAsync, boolean isGlobal) {
        // 获取全局或线程局部的监听器列表
        List<EventListenerWithPriority> listeners = isGlobal ? globalListeners.get(event) : threadLocalListeners.get().get(event);

        if (listeners != null) {
            // 按优先级排序监听器
            listeners.sort(Comparator.comparingInt(EventListenerWithPriority::getPriority));
        }
    }

    /**
     * 关闭事件管理器并释放线程池资源
     */
    public void shutdown() {
        executorService.shutdown();
    }

    /**
     * 内部类：事件监听器和优先级，包含监听器和其优先级、是否异步的状态
     */
    private static class EventListenerWithPriority {
        private final EventListener listener;
        private final int priority;
        private final boolean isAsync;  // 是否异步执行

        /**
         * 构造函数
         *
         * @param listener 事件监听器对象
         * @param isAsync 是否异步执行
         * @param priority 监听器的优先级
         */
        public EventListenerWithPriority(EventListener listener, boolean isAsync, int priority) {
            this.listener = listener;
            this.priority = priority;
            this.isAsync = isAsync;
        }

        public EventListener getListener() {
            return listener;
        }

        public int getPriority() {
            return priority;
        }

        public boolean isAsync() {
            return isAsync;  // 返回是否异步执行的状态
        }
    }

    /**
     * 事件监听器接口，所有事件监听器需要实现该接口
     */
    public interface EventListener {
        /**
         * 处理事件的方法
         *
         * @param event 事件消息
         */
        void onEvent(String event);
    }
}
